/*eslint-env node*/
'use strict';
(function () {
    var express = require('express');
    var cookieParser = require('cookie-parser')


    var compression = require('compression');
    var fs = require('fs');
    var url = require('url');
    var request = require('request');
    var cors = require('cors');
    var bodyParser = require('body-parser');
    var gzipHeader = Buffer.from('1F8B08', 'hex');
    const config = require('./config');
    var yargs = require('yargs').options({
        'port': {
            'default': 8081,
            'description': 'Port to listen on.'
        },
        'public': {
            'type': 'boolean',
            'description': 'Run a public server that listens on all interfaces.'
        },
        'upstream-proxy': {
            'description': 'A standard proxy server that will be used to retrieve data.  Specify a URL including port, e.g. "http://proxy:8000".'
        },
        'bypass-upstream-proxy-hosts': {
            'description': 'A comma separated list of hosts that will bypass the specified upstream_proxy, e.g. "lanhost1,lanhost2"'
        },
        'help': {
            'alias': 'h',
            'type': 'boolean',
            'description': 'Show this help.'
        }
    });
    var argv = yargs.argv;

    if (argv.help) {
        return yargs.showHelp();
    }

    // eventually this mime type configuration will need to change
    // https://github.com/visionmedia/send/commit/d2cb54658ce65948b0ed6e5fb5de69d022bef941
    // *NOTE* Any changes you make here must be mirrored in web.config.
    var mime = express.static.mime;
    mime.define({
        'application/json': ['czml', 'json', 'geojson', 'topojson'],
        'application/wasm': ['wasm'],
        'image/crn': ['crn'],
        'image/ktx': ['ktx'],
        'model/gltf+json': ['gltf'],
        'model/gltf-binary': ['bgltf', 'glb'],
        'application/octet-stream': ['b3dm', 'pnts', 'i3dm', 'cmpt', 'geom', 'vctr'],
        'text/plain': ['glsl']
    }, true);

    var app = express();
    app.use(compression());
    app.use(function (req, res, next) {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
        next();
    });
    app.use(cookieParser());
    app.use(cors());
    app.use(bodyParser.json()); //body-parser 解析json格式数据
    app.use(bodyParser.urlencoded({ //此项必须在 bodyParser.json 下面,为参数编码
        extended: false
    }));

    function checkGzipAndNext(req, res, next) {
        var reqUrl = url.parse(req.url, true);
        var filePath = reqUrl.pathname.substring(1);

        var readStream = fs.createReadStream(filePath, { start: 0, end: 2 });
        readStream.on('error', function (err) {
            next();
        });

        readStream.on('data', function (chunk) {
            if (chunk.equals(gzipHeader)) {
                res.header('Content-Encoding', 'gzip');
            }
            next();
        });
    }

    var knownTilesetFormats = [/\.b3dm/, /\.pnts/, /\.i3dm/, /\.cmpt/, /\.glb/, /\.geom/, /\.vctr/, /tileset.*\.json$/];
    app.get(knownTilesetFormats, checkGzipAndNext);

    app.use(express.static(__dirname));

    function getRemoteUrlFromParam(req) {
        var remoteUrl = req.params[0];
        if (remoteUrl) {
            // add http:// to the URL if no protocol is present
            if (!/^https?:\/\//.test(remoteUrl)) {
                remoteUrl = 'http://' + remoteUrl;
            }
            remoteUrl = url.parse(remoteUrl);
            // copy query string
            remoteUrl.search = url.parse(req.url).search;
        }
        return remoteUrl;
    }

    var dontProxyHeaderRegex = /^(?:Host|Proxy-Connection|Connection|Keep-Alive|Transfer-Encoding|TE|Trailer|Proxy-Authorization|Proxy-Authenticate|Upgrade)$/i;

    function filterHeaders(req, headers) {
        var result = {};
        // filter out headers that are listed in the regex above
        Object.keys(headers).forEach(function (name) {
            if (!dontProxyHeaderRegex.test(name)) {
                result[name] = headers[name];
            }
        });
        return result;
    }

    var upstreamProxy = argv['upstream-proxy'];
    var bypassUpstreamProxyHosts = {};
    if (argv['bypass-upstream-proxy-hosts']) {
        argv['bypass-upstream-proxy-hosts'].split(',').forEach(function (host) {
            bypassUpstreamProxyHosts[host.toLowerCase()] = true;
        });
    }


    app.all('*', function (req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "X-Requested-With");
        res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
        res.header("X-Powered-By", ' 3.2.1')
        res.header("Content-Type", "application/json;charset=utf-8");
        next();
    });

    //增
    app.post('/ADUS/admin/insertOb.action', function (req, res) {
        console.log("插入");
        console.log(req.cookies);
        var sheet = req.cookies['sheet'];
        console.log("插入" + sheet + "sheet");

        console.log("req.url :", req.url);
        console.log("req.body.name:", req.body.name);
        var name = req.body.name;
        var cnvd_id = req.body.cnvd_id;
        var disclosure_date = req.body.disclosure_date;
        var hazard_level = req.body.hazard_level;
        var impact_products = req.body.impact_products;
        var cve_id = req.body.cve_id;
        var description = req.body.description;
        var v_type = req.body.v_type;
        var reference = req.body.reference;
        var solution = req.body.solution;
        var vendor_patch = req.body.vendor_patch;
        var verification_info = req.body.verification_info;
        var reporting_date = req.body.reporting_date;
        var collection_date = req.body.collection_date;
        var update_date = req.body.update_date;
        var attachment = req.body.attachment;
        const Sequelize = require('sequelize');
        var sequelize = new Sequelize(config.database, config.username, config.password, {
            host: config.host,
            dialect: 'mysql',
            pool: {
                max: 5,
                min: 0,
                idle: 30000
            }
        });
        // 存入mysql
        var myMsg = sequelize.define(sheet, {
            v_id: {
                type: Sequelize.INTEGER,
                primaryKey: true,
            },
            name: Sequelize.STRING,
            cnvd_id: Sequelize.STRING,
            disclosure_date: Sequelize.STRING,
            hazard_level: Sequelize.STRING,
            impact_products: Sequelize.STRING,
            cve_id: Sequelize.STRING,
            description: Sequelize.STRING,
            v_type: Sequelize.STRING,
            reference: Sequelize.STRING,
            solution: Sequelize.STRING,
            vendor_patch: Sequelize.STRING,
            verification_info: Sequelize.STRING,
            reporting_date: Sequelize.STRING,
            collection_date: Sequelize.STRING,
            update_date: Sequelize.STRING,
            attachment: Sequelize.STRING,
        }, {
            freezeTableName: true,
            timestamps: false
        });
        console.log('mysql init');
        myMsg.create({

            name: name,
            cnvd_id: cnvd_id,
            disclosure_date: disclosure_date,
            hazard_level: hazard_level,
            impact_products: impact_products,
            cve_id: cve_id,
            description: description,
            v_type: v_type,
            reference: reference,
            solution: solution,
            vendor_patch: vendor_patch,
            verification_info: verification_info,
            reporting_date: reporting_date,
            collection_date: collection_date,
            update_date: update_date,
            attachment: attachment,
        }).then(function (p) {
            console.log('created.' + JSON.stringify(p));
            res.send("插入成功");
        }).catch(function (err) {
            console.log('failed: ' + err);
        });

    });
    var mysql = require('mysql');
    //查询
    app.get('/ADUS/admin/getObs.action', function (req, res) {
        var sheet = req.cookies['sheet'];
        console.log("查询" + sheet + "sheet");


        var connection = mysql.createConnection({
            host: config.host,
            user: config.username,
            password: config.password,
            database: config.database
        });
        connection.connect();
        //  connection.query('select GPS_LAT_CA,GPS_LONG_CA,ALT_STD,ROLL_RATE1 from fly order by Time desc ', function (err, data) {
        connection.query('select * from ' + sheet + "  order by v_id asc LIMIT 0,100;", function (err, data) {

            if (err) throw err;
            res.send(data);
            console.log("data.length:" + data.length)
        });
        connection.end();
    });
    //删除
    app.post('/ADUS/admin/deleteObById.action', function (req, res) {
        console.log("deleteObById");
        var sheet = req.cookies['sheet'];
        console.log("删除" + sheet + "sheet");
        var v_id = req.body.v_id;
        console.log("v_id:" + v_id);
        var connection = mysql.createConnection({
            host: config.host,
            user: config.username,
            password: config.password,
            database: config.database
        });
        connection.connect();
        //  connection.query('select GPS_LAT_CA,GPS_LONG_CA,ALT_STD,ROLL_RATE1 from fly order by Time desc ', function (err, data) {
        connection.query('delete from ' + sheet + "  where v_id=" + v_id, function (err, data) {

            if (err) throw err;
            res.send("删除成功");
            console.log("删除成功");
        });
        connection.end();
    });
    //更新
    app.post('/ADUS/admin/updateObById.action', function (req, res) {
        console.log(req.cookies);
        var sheet = req.cookies['sheet'];
        console.log("sheet:" + sheet);
        console.log("req.url :", req.url);

        console.log("req.body:", req.body);
        var v_id = req.body.v_id;
        console.log("v_id:", v_id);

        var name = req.body.name;
        var cnvd_id = req.body.cnvd_id;
        var disclosure_date = req.body.disclosure_date;
        var hazard_level = req.body.hazard_level;
        var impact_products = req.body.impact_products;
        var cve_id = req.body.cve_id;
        var description = req.body.description;
        var v_type = req.body.v_type;
        var reference = req.body.reference;
        var solution = req.body.solution;
        var vendor_patch = req.body.vendor_patch;
        var verification_info = req.body.verification_info;
        var reporting_date = req.body.reporting_date;
        var collection_date = req.body.collection_date;
        var update_date = req.body.update_date;
        var attachment = req.body.attachment;
        let connection = mysql.createConnection({
            host: config.host,
            user: config.username,
            password: config.password,
            database: config.database
        });

        connection.connect((err, result) => {
            if (err) {
                console.log(err);
                console.log("连接失败");
                return;
            }
            console.log(result);
            console.log("连接成功");
        });

        /**
         * -------------------
         * 更新数据
         * -------------------
         */

        let modSql = 'UPDATE ' + sheet + ' SET name = ?,cnvd_id = ?,disclosure_date = ?,hazard_level = ?,impact_products = ?,cve_id = ?,description = ?, v_type = ?, reference = ?, solution = ?, vendor_patch = ?, verification_info = ?, reporting_date = ?, collection_date = ?, update_date = ?, attachment = ? WHERE v_id = ? ';
        let modSqlParams = [name, cnvd_id, disclosure_date, hazard_level, impact_products, cve_id, description, v_type, reference, solution, vendor_patch, verification_info, reporting_date, collection_date, update_date, attachment, v_id];

        var query = connection.query(modSql, modSqlParams, (err, result) => {
            if (err) {
                console.log('[更新失败] - ', err.message);
                return;
            }

            console.log('----------UPDATE---------------');
            console.log('更新成功', result.affectedRows);
            console.log('query.sql' + query.sql);

            res.send("更新成功");
            console.log('-------------------------------\n\n');
        });
        connection.end();

    });
    app.get('/proxy/*', function (req, res, next) {
        // look for request like http://localhost:8080/proxy/http://example.com/file?query=1
        var remoteUrl = getRemoteUrlFromParam(req);
        if (!remoteUrl) {
            // look for request like http://localhost:8080/proxy/?http%3A%2F%2Fexample.com%2Ffile%3Fquery%3D1
            remoteUrl = Object.keys(req.query)[0];
            if (remoteUrl) {
                remoteUrl = url.parse(remoteUrl);
            }
        }

        if (!remoteUrl) {
            return res.status(400).send('No url specified.');
        }

        if (!remoteUrl.protocol) {
            remoteUrl.protocol = 'http:';
        }

        var proxy;
        if (upstreamProxy && !(remoteUrl.host in bypassUpstreamProxyHosts)) {
            proxy = upstreamProxy;
        }

        // encoding : null means "body" passed to the callback will be raw bytes

        request.get({
            url: url.format(remoteUrl),
            headers: filterHeaders(req, req.headers),
            encoding: null,
            proxy: proxy
        }, function (error, response, body) {
            var code = 500;

            if (response) {
                code = response.statusCode;
                res.header(filterHeaders(req, response.headers));
            }

            res.status(code).send(body);
        });
    });

    var server = app.listen(argv.port, argv.public ? undefined : 'localhost', function () {
        if (argv.public) {
            console.log('ADUS development server running publicly.  Connect to http://localhost:%d/', server.address().port);
        } else {
            console.log('ADUS development server running locally.  Connect to http://localhost:%d/', server.address().port);
        }
    });



    server.on('error', function (e) {
        if (e.code === 'EADDRINUSE') {
            console.log('Error: Port %d is already in use, select a different port.', argv.port);
            console.log('Example: node server.js --port %d', argv.port + 1);
        } else if (e.code === 'EACCES') {
            console.log('Error: This process does not have permission to listen on port %d.', argv.port);
            if (argv.port < 1024) {
                console.log('Try a port number higher than 1024.');
            }
        }
        console.log(e);
        process.exit(1);
    });

    server.on('close', function () {
        console.log('ADUS development server stopped.');
    });

    var isFirstSig = true;
    process.on('SIGINT', function () {
        if (isFirstSig) {
            console.log('ADUS development server shutting down.');
            server.close(function () {
                process.exit(0);
            });
            isFirstSig = false;
        } else {
            console.log('Cesium development server force kill.');
            process.exit(1);
        }
    });



})();